package org.example.backend.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.example.backend.constant.ResultCode;
import org.example.backend.dto.LoginDTO;
import org.example.backend.dto.PageResult;
import org.example.backend.dto.Result;
import org.example.backend.entity.Leader;
import org.example.backend.entity.User;
import org.example.backend.exception.BusinessException;
import org.example.backend.mapper.LeaderMapper;
import org.example.backend.mapper.UserMapper;
import org.example.backend.util.MD5Util;
import org.example.backend.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户管理控制器
 * 提供用户登录、查询、新增、修改、删除等功能
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LeaderMapper leaderMapper;

    /**
     * 用户登录
     * @param loginDTO 登录信息DTO，包含用户名和密码
     * @return 登录结果，包含用户ID、用户名、角色和token
     */
    @PostMapping("/login")
    public ResponseEntity<Result<Map<String, Object>>> login(@Valid @RequestBody LoginDTO loginDTO) {
        if (StringUtils.isBlank(loginDTO.getUsername()) || StringUtils.isBlank(loginDTO.getPassword())) {
            return ResponseUtil.badRequest("用户名或密码不能为空");
        }

        LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>lambdaQuery()
                .eq(User::getUsername, loginDTO.getUsername())
                .eq(User::getPassword, MD5Util.encrypt(loginDTO.getPassword()));

        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            return ResponseUtil.badRequest("用户名或密码错误");
        }

        if (user.getStatus() == 0) {
            return ResponseUtil.forbidden("账号已被禁用");
        }

        // 验证用户角色与登录入口是否匹配
        if (!user.getRole().equals(loginDTO.getRole())) {
            return ResponseUtil.forbidden("请使用正确的登录入口");
        }

        Map<String, Object> data = new HashMap<>();
        data.put("id", user.getId());
        data.put("username", user.getUsername());
        data.put("role", user.getRole());

        // 如果是团长角色，需要查询对应的团长ID
        if ("leader".equals(user.getRole())) {
            Leader leader = leaderMapper.selectOne(
                Wrappers.<Leader>lambdaQuery()
                    .eq(Leader::getUserId, user.getId())
            );

            if (leader != null) {
                data.put("leaderId", leader.getId());
            }
        }

        // 实际项目中应该使用JWT等方式生成token
        data.put("token", "admin-token");

        return ResponseUtil.success(data);
    }

    /**
     * 获取用户信息
     * @param userId 用户ID
     * @return 用户信息（已脱敏）
     */
    @GetMapping("/info")
    public ResponseEntity<Result<User>> getUserInfo(@RequestParam Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            return ResponseUtil.notFound("用户不存在");
        }
        // 脱敏处理
        user.setPassword(null);
        return ResponseUtil.success(user);
    }

    /**
     * 分页查询用户列表
     * @param current 当前页码
     * @param size 每页大小
     * @param username 用户名（可选，模糊查询）
     * @param role 角色（可选，精确查询）
     * @return 分页结果
     */
    @GetMapping("/page")
    public ResponseEntity<Result<PageResult<User>>> page(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String username,
            @RequestParam(required = false) String role) {

        Page<User> page = new Page<>(current, size);

        LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>lambdaQuery()
                .like(StringUtils.isNotBlank(username), User::getUsername, username)
                .eq(StringUtils.isNotBlank(role), User::getRole, role)
                .orderByDesc(User::getCreateTime);

        Page<User> userPage = userMapper.selectPage(page, queryWrapper);

        // 脱敏处理
        userPage.getRecords().forEach(user -> user.setPassword(null));

        return ResponseUtil.success(new PageResult<>(userPage.getTotal(), userPage.getRecords()));
    }

    /**
     * 新增用户
     * @param user 用户信息
     * @return 操作结果
     */
    @PostMapping
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW)
    public ResponseEntity<Result<Long>> save(@Valid @RequestBody User user) {
        try {
            // 检查用户名是否已存在
            Long count = userMapper.selectCount(
                Wrappers.<User>lambdaQuery()
                    .eq(User::getUsername, user.getUsername())
                    .last("FOR UPDATE")
            );
            if (count > 0) {
                throw new BusinessException(ResultCode.DATA_ALREADY_EXISTED, "用户名已存在");
            }
            
            // 检查手机号是否已存在
            Long phoneCount = userMapper.selectCount(
                Wrappers.<User>lambdaQuery()
                    .eq(User::getPhone, user.getPhone())
                    .last("FOR UPDATE")
            );
            if (phoneCount > 0) {
                throw new BusinessException(ResultCode.DATA_ALREADY_EXISTED, "手机号已被注册");
            }
            
            // 密码加密
            user.setPassword(MD5Util.encrypt(user.getPassword()));
            
            userMapper.insert(user);
            return ResponseUtil.success(user.getId());
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ResultCode.SERVER_ERROR, "创建用户失败: " + e.getMessage());
        }
    }

    /**
     * 修改用户
     * @param user 用户信息
     * @return 操作结果
     */
    @PutMapping
    public ResponseEntity<Result<Void>> update(@Valid @RequestBody User user) {
        if (user.getId() == null) {
            return ResponseUtil.badRequest("ID不能为空");
        }

        User existUser = userMapper.selectById(user.getId());
        if (existUser == null) {
            return ResponseUtil.notFound("用户不存在");
        }

        // 如果密码为空，则使用原密码
        if (StringUtils.isBlank(user.getPassword())) {
            user.setPassword(existUser.getPassword());
        } else {
            // 密码加密
            user.setPassword(MD5Util.encrypt(user.getPassword()));
        }

        userMapper.updateById(user);
        return ResponseUtil.success();
    }

    /**
     * 删除用户
     * @param id 用户ID
     * @return 操作结果
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Result<Void>> delete(@PathVariable Long id) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return ResponseUtil.notFound("用户不存在");
        }

        userMapper.deleteById(id);
        return ResponseUtil.success();
    }

    /**
     * 更新用户状态
     * @param id 用户ID
     * @param status 状态值（0-禁用，1-启用）
     * @return 操作结果
     */
    @PutMapping("/status")
    public ResponseEntity<Result<Void>> updateStatus(@RequestParam Long id, @RequestParam Integer status) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return ResponseUtil.notFound("用户不存在");
        }

        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setStatus(status);
        userMapper.updateById(updateUser);
        return ResponseUtil.success();
    }

    /**
     * 检查手机号是否已被注册
     * @param phone 手机号
     * @return true-已存在，false-不存在
     */
    @GetMapping("/check-phone")
    public ResponseEntity<Result<Boolean>> checkPhoneExists(@RequestParam String phone) {
        Long count = userMapper.selectCount(Wrappers.<User>lambdaQuery().eq(User::getPhone, phone));
        return ResponseUtil.success(count > 0);
    }
}
